#!/bin/bash
#
# This is a reference module showcasing the shell API for writing
# OpenPanel modules.

# Include the shell API wrapper
. /var/opencore/api/sh/module.sh

# ----------------------------------------------------------------------------
# Constructor for class Storpel
# ----------------------------------------------------------------------------
Storpel.create() {
  # Get the id of the associated Actor (unix user). Not that we're
  # actually using it at this point, but it's nice to know you
  # can access the id of parents in the object chain.
  actor_id=`coreval Actor id`
  
  # In module.xml we defined one parameter for our class: 'model'. This
  # parameter will be passed from the user interface.
  model=`coreval Storpel model`
  
  # Let's wonder about an arbitrary error condition, in this case we
  # will reject Storpel objects with their 'model' parameter set to
  # 100.
  if [ "$model" = "100" ]; then
  
    # The exiterror command will send the error xml and exit the
    # module.
    exiterror "Model out of production"
  fi
  
  id=`coreval Storpel id`
  
  # Create a staging file. The setting of <uniquein>class</uniquein> inside
  # module.xml guarantees the metaid is globally unique, so it is safe to
  # use the objectid as a filename.
  echo "Model $model" > "${id}.storpel"
  echo "Hostname ${id}" >> "${id}.storpel"
  
  # Go over the Domain -> Domain:Alias object list
  listaliases | while read a; do
    echo "Alias ${a}" >> "${id}.storpel"
  done
  
  # Go over the StorpelUser sub-objects that we got thanks to
  # allchildren.
  coreval --loop Storpel StorpelUser | while read userid; do
    password=`coreval Storpel StorpelUser "$userid" password`
    echo "User ${userid}:${password}" >> "${id}.storpel"
  done
  
  # Call authd to install the file from our staging directory straight
  # into the /etc/storpels system directory. If you want it simpler,
  # you can still choose to bypass authd and just offer full access to
  # the configuration directory of your program to the opencore group. The
  # authd system is intended to add a layer of auditing and authorization
  # making it less likely that your module gets subverted to act beyond its
  # intended operations.
  authd installfile "${id}.storpel" /etc/storpels
  
  # There is no need to worry about authd failures. If an authd command
  # fails, the program wil exit itself with an error message and a
  # rollback. If this is not what you want, you can call try_authd() instead
  # and check its return value for failures.
}

# ----------------------------------------------------------------------------
# Destructor for class Storpel
# ----------------------------------------------------------------------------
Storpel.delete() {
  # We'll only need the objectid for this task
  id=`coreval OpenCORE:Session objectid`
  
  # Leave it to authd
  authd deletefile "/etc/storpels/${id}.storpel"
  
  # Delete the local staging file as well.
  rm -f "${id}.storpel"
}

# ----------------------------------------------------------------------------
# Update method for class Storpel
# ----------------------------------------------------------------------------
Storpel.update() {
  Storpel.create
}

# ----------------------------------------------------------------------------
# Constructor for StorpelUser
# ----------------------------------------------------------------------------
StorpelUser.create() {
  # Delegate to Storpel, it'll pick us up through allchildren
  Storpel.update
}

# ----------------------------------------------------------------------------
# Update method for StorpelUser
# ----------------------------------------------------------------------------
StorpelUser.update() {
  # Delegate to Storpel, it'll pick us up through allchildren
  Storpel.update
}

# ----------------------------------------------------------------------------
# Destructor for StorpelUser
# ----------------------------------------------------------------------------
StorpelUser.delete() {
  # Delegate to Storpel, it'll pick us up through allchildren
  Storpel.update
}

# ----------------------------------------------------------------------------
# Constructor for class StorpelService
# ----------------------------------------------------------------------------
StorpelService.create() {
  listenport=`coreval StorpelService listenport`
  servername=`coreval StorpelService servername`
  cat > storpeld.conf << _EOF_
[system]
ListenPort = $listenport
ServerName = "$servername"
_EOF_
  authd installfile storpeld.conf /etc
}

# ----------------------------------------------------------------------------
# Update method for class StorpelService
# ----------------------------------------------------------------------------
StorpelService.update() {
  StorpelService.create
}

# ----------------------------------------------------------------------------
# Destructor for class StorpelService
# ----------------------------------------------------------------------------
StorpelService.delete() {
  exiterror "Delete not implemented"
}

# ----------------------------------------------------------------------------
# Install-time configuration
# ----------------------------------------------------------------------------
Module.getconfig() {
  cat << _EOF_
  <dict id="StorpelService" type="class">
    <dict id="storpeld">
      <integer id="listenport">1234</integer>
      <string id="servername">Default Servername</string>
    </dict>
  </dict>
_EOF_
}

# ----------------------------------------------------------------------------
# Enable actual handling of module drudgery.
# ----------------------------------------------------------------------------
implement Storpel.module

